package org.jeecg.modules.mes.storage.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.lang3.StringUtils;
import org.jeecg.modules.mes.client.ProduceClient;
import org.jeecg.modules.mes.client.SystemClient;
import org.jeecg.modules.mes.client.TransactionClient;
import org.jeecg.modules.mes.produce.entity.MesCommandbillInfo;
import org.jeecg.modules.mes.produce.entity.MesCommandbillPitem;
import org.jeecg.modules.mes.produce.entity.TurnProduceRecord;
import org.jeecg.modules.mes.storage.entity.MesCertificateItem;
import org.jeecg.modules.mes.storage.entity.MesMaterielOccupy;
import org.jeecg.modules.mes.storage.mapper.MesCertificateItemMapper;
import org.jeecg.modules.mes.storage.service.IMesCertificateItemService;
import org.jeecg.modules.mes.storage.service.IMesMaterielOccupyService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.List;

/**
 * @Description: 物料凭证项目
 * @Author: jeecg-boot
 * @Date:   2020-10-15
 * @Version: V1.0
 */
@Service
public class MesCertificateItemServiceImpl extends ServiceImpl<MesCertificateItemMapper, MesCertificateItem> implements IMesCertificateItemService {
	
	@Autowired
	private MesCertificateItemMapper mesCertificateItemMapper;

	@Autowired
	private IMesMaterielOccupyService mesMaterielOccupyService;

	@Autowired
	TransactionClient transactionClient;

	@Autowired
	ProduceClient produceClient;

	@Autowired
	SystemClient systemClient;

	@Override
	public List<MesCertificateItem> selectByMainId(String mainId) {
		return mesCertificateItemMapper.selectByMainId(mainId);
	}
	/**
	 * 根据打印的标签二维码获取他的item质检信息
	 * @param query4
	 * @return
	 */
	@Override
	public List<MesCertificateItem> selectbqByItem(String query4){
		return mesCertificateItemMapper.selectbqByItem(query4);
	}

	/**
	 * 制令单批量转产
	 * @param mesCertificateItem
	 * @return
	 */
	@Transactional
	public boolean wholeChangeProduce(MesCertificateItem mesCertificateItem){
		String perkId = mesCertificateItem.getPerkId();
		String mobileType = mesCertificateItem.getMobileType();
		String materielCode = mesCertificateItem.getMaterielCode();
		if (StringUtils.isNotBlank(perkId) && StringUtils.isNotBlank(mobileType)) {
			QueryWrapper<MesCertificateItem> wrapper = new QueryWrapper<>();
			if (StringUtils.isNotBlank(materielCode)) {
				wrapper.eq("perk_id", perkId).eq("mobile_type", mobileType).eq("materiel_code", materielCode);
			} else {
				wrapper.eq("perk_id", perkId).eq("mobile_type", mobileType);
			}
			List<MesCertificateItem> certificateItemList = this.list(wrapper);
			String mobileCode = "268";
			if (certificateItemList.size() == 0) {
				//268 制令单批量转产
				if (mesCertificateItem.getMobileCode().equals(mobileCode)) {
					//原制令单bom表信息
					List<MesCommandbillPitem> mesCommandbillPitemList = mesCertificateItem.getMesCommandbillPitemList();
					if (mesCommandbillPitemList.size() != 0) {
						String changeCode = mesCertificateItem.getQuery5();//转产制令单号
						for (MesCommandbillPitem commandbillPitem : mesCommandbillPitemList) {//遍历原有制令单bom信息
							String mCode = commandbillPitem.getMaterielCode();//原有物料料号

							//原制令单的数量信息归纳
							BigDecimal deliveryNum = new BigDecimal(commandbillPitem.getDeliveryNum());//已发料数量
							BigDecimal consumeNum = new BigDecimal(commandbillPitem.getConsumeNum());//已消耗数量
							BigDecimal withdrawNum = new BigDecimal(commandbillPitem.getWithdrawNum());//已退料料数量
							if (StringUtils.isBlank(commandbillPitem.getTransformNum())) {
								commandbillPitem.setTransformNum("0");
							}
							BigDecimal transformNum = new BigDecimal(commandbillPitem.getTransformNum());//已转产数量
							BigDecimal adviceNum = deliveryNum.subtract(consumeNum.add(withdrawNum).add(transformNum));//建议转产数量=已发料数量-（已消耗数量+已退料料数量+已转产数量）
							BigDecimal realNum = new BigDecimal(commandbillPitem.getVirtualNum());//实际转产数量
							if (realNum.compareTo(adviceNum) == 1) {
								throw new RuntimeException("原制令单物料"+commandbillPitem.getMaterielCode()+"转产数量不对！请检查！");
							}

							//执行bom的转产操作
							//通过转产制令单号和物料料号，通过远程调用，获取转产制令单Bom的数据
							MesCommandbillPitem pitem = produceClient.getPitemByCode(changeCode, mCode);
							//没有查询出来的进入退料操作
							if (pitem != null) {
								//进入转产操作
								if (StringUtils.isNotBlank(mCode)
										&&StringUtils.isNotBlank(commandbillPitem.getProorderId())
										&&StringUtils.isNotBlank(pitem.getProorderId())) {
									//通过订单id与物料料号，查询领料表信息
									String produceId = commandbillPitem.getProorderId();//原有制令单关联的生产订单id
									String orderId = pitem.getProorderId();//转产制令单关联的生产订单id
									if (!produceId.equals(orderId)) {
										QueryWrapper<MesMaterielOccupy> occupyWrapper = new QueryWrapper<>();
										occupyWrapper.eq("order_id", produceId).eq("materiel_code", mCode);
										MesMaterielOccupy materielOccupy = mesMaterielOccupyService.getOne(occupyWrapper);
										if (materielOccupy != null) {
											BigDecimal transNewnum = transformNum.add(realNum);//新的转产数量 = 已转产数量 + 转产数量
											//更新领料表的转产数量
											materielOccupy.setTransformNum(transNewnum.toString());
											mesMaterielOccupyService.updateById(materielOccupy);
											//更新原有制令单Bom表的转产数量
											commandbillPitem.setTransformNum(transformNum.toString());
											produceClient.editComitem(commandbillPitem);
										} else {
											throw new RuntimeException("没有找到原有制令单的物料领用信息！请检查！");
										}

										QueryWrapper<MesMaterielOccupy> materielOccupyWrapper = new QueryWrapper<>();
										materielOccupyWrapper.eq("order_id", orderId).eq("materiel_code", mCode);
										MesMaterielOccupy mesMaterielOccupy = mesMaterielOccupyService.getOne(materielOccupyWrapper);
										if (mesMaterielOccupy != null) {
											BigDecimal originalNum = new BigDecimal(pitem.getDeliveryNum());//原有的数量
											BigDecimal deliveryNewnum = originalNum.add(realNum);//新的发料数量 = 原有数量 + 转产数量
											//更新领料表的发料数量
											mesMaterielOccupy.setSendNum(deliveryNewnum.toString());
											mesMaterielOccupyService.updateById(mesMaterielOccupy);
											//更新转产制令单Bom表的发料数量
											pitem.setDeliveryNum(deliveryNewnum.toString());
											produceClient.editComitem(pitem);
										} else {
											throw new RuntimeException("没有找到转产制令单的物料领用信息！请检查！");
										}
									} else {
										BigDecimal transNewnum = transformNum.add(realNum);//新的转产数量 = 已转产数量 + 转产数量
										commandbillPitem.setTransformNum(transNewnum.toString());
										produceClient.editComitem(commandbillPitem);

										BigDecimal originalNum = new BigDecimal(pitem.getDeliveryNum());//原有的数量
										BigDecimal deliveryNewnum = originalNum.add(realNum);//新的发料数量 = 原有数量 + 转产数量
										pitem.setDeliveryNum(deliveryNewnum.toString());
										produceClient.editComitem(pitem);

									}
								} else {
									throw new RuntimeException("制令单Bom表里没有查询到订单id和物料料号！请检查！");
								}

								mesCertificateItem.setId(null);
								mesCertificateItem.setInputNum(realNum.toString());//退料数量
								BeanUtils.copyProperties(commandbillPitem, mesCertificateItem);
								mesCertificateItem.setId(null);//主键设置为null
								mesCertificateItem.setCreateBy(null);//创建人设置为null
								mesCertificateItem.setCreateTime(null);//创建时间设置为null
								mesCertificateItem.setInputUnit(commandbillPitem.getCountUnit());//单位
								mesCertificateItem.setFactoryCode("批量转产");//类型
								mesCertificateItem.setFactoryName("原单号: " + commandbillPitem.getCommandbillCode()); //原制令单
								mesCertificateItem.setStorageSite("转产单号: " + pitem.getCommandbillCode());//转产制令单号
								this.save(mesCertificateItem);
								//转产记录表
								MesCommandbillInfo commandbill = produceClient.getById(commandbillPitem.getCommandbillId());//原制令单
								MesCommandbillInfo commandbill2 = produceClient.getById(pitem.getCommandbillId());//转产制令单
								TurnProduceRecord turnProduceRecord = new TurnProduceRecord();
								turnProduceRecord.setCommandbillId(commandbillPitem.getCommandbillId());
								turnProduceRecord.setCommandbillCode(commandbillPitem.getCommandbillCode());
								turnProduceRecord.setMechanismCode(commandbill.getMechanismCode());
								turnProduceRecord.setMechanismName(commandbill.getMechanismName());
								turnProduceRecord.setZcommandbillId(pitem.getCommandbillId());
								turnProduceRecord.setZcommandbillCode(pitem.getCommandbillCode());
								turnProduceRecord.setZmechanismCode(commandbill2.getMechanismCode());
								turnProduceRecord.setZmechanismName(commandbill2.getMechanismName());
								turnProduceRecord.setProductCode(commandbillPitem.getMaterielCode());
								turnProduceRecord.setProductName(commandbillPitem.getMaterielName());
								turnProduceRecord.setSurplusNum(realNum.toString());
								turnProduceRecord.setState("转产");
								produceClient.TurnProduceRecordadd(turnProduceRecord);
							}else{
								if (StringUtils.isNotBlank(commandbillPitem.getProorderId())){
									//制令单退料时，将退料数量记录在物料领用表，并返回到库存上
									QueryWrapper<MesMaterielOccupy> occupyWrapper = new QueryWrapper<>();
									occupyWrapper.eq("order_id", commandbillPitem.getProorderId()).eq("materiel_code", mCode);
									MesMaterielOccupy materielOccupy = mesMaterielOccupyService.getOne(occupyWrapper);
									if (materielOccupy != null) {
										BigDecimal withdrawNewnum = withdrawNum.add(realNum);//新的退料数量 = 已退料数量 + 退料数量
										//更新领料表的转产数量
										materielOccupy.setWithdrawNum(withdrawNewnum.toString());
										mesMaterielOccupyService.updateById(materielOccupy);
										//更新原有制令单Bom表的转产数量
										commandbillPitem.setWithdrawNum(withdrawNewnum.toString());
										produceClient.editComitem(commandbillPitem);
									} else {
										throw new RuntimeException("没有找到原有制令单的物料领用信息！请检查！");
									}
								}else{
									throw new RuntimeException("制令单Bom表里没有查询到生产订单id！请检查！");
								}
								//退料记录
								MesCommandbillInfo commandbill = produceClient.getById(commandbillPitem.getCommandbillId());//原制令单
								MesCommandbillInfo commandbill2 = produceClient.getById(pitem.getCommandbillId());//转产制令单
								TurnProduceRecord turnProduceRecord = new TurnProduceRecord();
								turnProduceRecord.setCommandbillId(commandbillPitem.getCommandbillId());
								turnProduceRecord.setCommandbillCode(commandbillPitem.getCommandbillCode());
								turnProduceRecord.setMechanismCode(commandbill.getMechanismCode());
								turnProduceRecord.setMechanismName(commandbill.getMechanismName());
								turnProduceRecord.setZcommandbillId(pitem.getCommandbillId());
								turnProduceRecord.setZcommandbillCode(pitem.getCommandbillCode());
								turnProduceRecord.setZmechanismCode(commandbill2.getMechanismCode());
								turnProduceRecord.setZmechanismName(commandbill2.getMechanismName());
								turnProduceRecord.setProductCode(commandbillPitem.getMaterielCode());
								turnProduceRecord.setProductName(commandbillPitem.getMaterielName());
								turnProduceRecord.setSurplusNum(realNum.toString());
								turnProduceRecord.setState("退料");
								produceClient.TurnProduceRecordadd(turnProduceRecord);
							}
						}
					} else {
						throw new RuntimeException("没有找到制令单BOM的数据！请检查！");
					}
				} else {
					throw new RuntimeException("制令单批量转产时移动编号不等于268！请检查");
				}
			} else if (certificateItemList.size() >= 1) {
				if (mesCertificateItem.getMobileCode().equals(mobileCode)) {
					List<MesCommandbillPitem> mesCommandbillPitemList = mesCertificateItem.getMesCommandbillPitemList();
					if (mesCommandbillPitemList.size() != 0) {
						String changeCode = mesCertificateItem.getQuery5();//转产制令单号
						for (MesCommandbillPitem commandbillPitem : mesCommandbillPitemList) {
							String mCode = commandbillPitem.getMaterielCode();//物料料号
							BigDecimal deliveryNum = new BigDecimal(commandbillPitem.getDeliveryNum());//已发料数量
//								BigDecimal glazeNum = new BigDecimal(commandbillPitem.getUnglazeNum());//已上料数量
							BigDecimal consumeNum = new BigDecimal(commandbillPitem.getConsumeNum());//已消耗数量
							BigDecimal withdrawNum = new BigDecimal(commandbillPitem.getWithdrawNum());//已退料料数量
							if (StringUtils.isBlank(commandbillPitem.getTransformNum())) {
								commandbillPitem.setTransformNum("0");
							}
							BigDecimal transformNum = new BigDecimal(commandbillPitem.getTransformNum());//已转产数量
							BigDecimal adviceNum = deliveryNum.subtract(consumeNum.add(withdrawNum).add(transformNum));//建议转产数量
							BigDecimal realNum = new BigDecimal(commandbillPitem.getVirtualNum());//实际转产数量
							if (realNum.compareTo(adviceNum) == 1) {
								throw new RuntimeException("原制令单物料"+commandbillPitem.getMaterielCode()+"转产数量不对！请检查！");
							}
							//通过转产制令单号和物料料号，通过远程调用，获取转产制令单Bom的数据
							MesCommandbillPitem pitem = produceClient.getPitemByCode(changeCode, mCode);
							if (pitem != null) {
									//进入转产操作
									if (StringUtils.isNotBlank(commandbillPitem.getProorderId()) &&
											StringUtils.isNotBlank(pitem.getProorderId()) &&
											StringUtils.isNotBlank(mCode)) {
										//通过订单id与物料料号，查询领料表信息
										String orderId = pitem.getProorderId();//转产制令单关联的生产订单id
										String produceId = commandbillPitem.getProorderId();//原有制令单关联的生产订单id
										if (!produceId.equals(orderId)) {
											QueryWrapper<MesMaterielOccupy> occupyWrapper = new QueryWrapper<>();
											occupyWrapper.eq("order_id", produceId).eq("materiel_code", mCode);
											MesMaterielOccupy materielOccupy = mesMaterielOccupyService.getOne(occupyWrapper);
											if (materielOccupy != null) {
												BigDecimal transNewnum = transformNum.add(realNum);//新的转产数量 = 已转产数量 + 转产数量
												//更新领料表的转产数量
												materielOccupy.setTransformNum(transNewnum.toString());
												mesMaterielOccupyService.updateById(materielOccupy);
												//更新原有制令单Bom表的转产数量
												commandbillPitem.setTransformNum(transformNum.toString());
												produceClient.editComitem(commandbillPitem);
											} else {
												throw new RuntimeException("没有找到原有制令单的物料领用信息！请检查！");
											}

											QueryWrapper<MesMaterielOccupy> materielOccupyWrapper = new QueryWrapper<>();
											materielOccupyWrapper.eq("order_id", orderId).eq("materiel_code", mCode);
											MesMaterielOccupy mesMaterielOccupy = mesMaterielOccupyService.getOne(materielOccupyWrapper);
											if (mesMaterielOccupy != null) {
												BigDecimal originalNum = new BigDecimal(pitem.getDeliveryNum());//原有的数量
												BigDecimal deliveryNewnum = originalNum.add(realNum);//新的发料数量 = 原有数量 + 转产数量
												//更新领料表的退料数量
												mesMaterielOccupy.setSendNum(deliveryNewnum.toString());
												mesMaterielOccupyService.updateById(mesMaterielOccupy);
												//更新转产制令单Bom表的发料数量
												pitem.setDeliveryNum(deliveryNewnum.toString());
												produceClient.editComitem(pitem);
											} else {
												throw new RuntimeException("没有找到转产制令单的物料领用信息！请检查！");
											}
										} else {
											BigDecimal transNewnum = transformNum.add(realNum);//新的转产数量 = 已转产数量 + 转产数量
											commandbillPitem.setTransformNum(transNewnum.toString());
											produceClient.editComitem(commandbillPitem);

											BigDecimal originalNum = new BigDecimal(pitem.getDeliveryNum());//原有的数量
											BigDecimal deliveryNewnum = originalNum.add(realNum);//新的发料数量 = 原有数量 + 转产数量
											pitem.setDeliveryNum(deliveryNewnum.toString());
											produceClient.editComitem(pitem);
										}
										//更新物料凭证数量
										QueryWrapper<MesCertificateItem> certificateWrapper = new QueryWrapper<>();
										certificateWrapper.eq("materiel_code", mCode).eq("perk_id", perkId).eq("mobile_code", "268");
										MesCertificateItem certificateItem = this.getOne(certificateWrapper);
										if (certificateItem != null) {
											BigDecimal certificateOldNum = new BigDecimal(certificateItem.getInputNum());
											BigDecimal certificateNum = certificateOldNum.add(realNum);
											certificateItem.setInputNum(certificateNum.toString());
											this.updateById(certificateItem);
										} else {
											throw new RuntimeException("没有找到物料凭证项目数据！请检查！");
										}

									} else {
										throw new RuntimeException("制令单Bom表里没有查询到订单id和物料料号！请检查！");
									}
							} else {
								if (StringUtils.isNotBlank(commandbillPitem.getProorderId())){
									//制令单退料时，将退料数量记录在物料领用表，并返回到库存上
									QueryWrapper<MesMaterielOccupy> occupyWrapper = new QueryWrapper<>();
									occupyWrapper.eq("order_id", commandbillPitem.getProorderId()).eq("materiel_code", mCode);
									MesMaterielOccupy materielOccupy = mesMaterielOccupyService.getOne(occupyWrapper);
									if (materielOccupy != null) {
										BigDecimal withdrawNewnum = withdrawNum.add(realNum);//新的退料数量 = 已退料数量 + 退料数量
										//更新领料表的转产数量
										materielOccupy.setWithdrawNum(withdrawNewnum.toString());
										mesMaterielOccupyService.updateById(materielOccupy);
										//更新原有制令单Bom表的转产数量
										commandbillPitem.setWithdrawNum(withdrawNewnum.toString());
										produceClient.editComitem(commandbillPitem);
									} else {
										throw new RuntimeException("没有找到原有制令单的物料领用信息！请检查！");
									}
								}else{
									throw new RuntimeException("制令单Bom表里没有查询到生产订单id！请检查！");
								}
							}
						}
					} else {
						throw new RuntimeException("没有找到制令单BOM的数据！请检查！");
					}
				} else {
					throw new RuntimeException("制令单批量转产时移动编号不等于268！请检查");
				}
			}
		} else {
			throw new RuntimeException("没有找到凭证抬头ID和移动类型！请检查");
		}
		return  true;
	}
}
